package com.ruoyi.pos.api.service.user.impl;

import com.ruoyi.common.enums.*;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtil;
import com.ruoyi.common.utils.SaltUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.json.JsonUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.weCat.WeCatUtils;
import com.ruoyi.pos.api.dto.user.OrderDto;
import com.ruoyi.pos.api.service.common.ICommonService;
import com.ruoyi.pos.api.service.task.IOrderTaskService;
import com.ruoyi.pos.api.service.user.IOrderService;
import com.ruoyi.pos.api.utils.CommonUtils;
import com.ruoyi.pos.api.vo.common.ConfirmOrderVo;
import com.ruoyi.pos.api.vo.common.TUserAddressVo;
import com.ruoyi.pos.api.vo.user.OrderDetailVo;
import com.ruoyi.pos.api.vo.user.OrderListVo;
import com.ruoyi.pos.web.domain.*;
import com.ruoyi.pos.web.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author luobo
 * @title: OrderServiceImpl
 * @projectName pos
 * @description: TODO
 * @date 2021-11-08 08:36:25
 */
@Service
public class OrderServiceImpl implements IOrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private TUserInfoMapper userInfoMapper;
    @Autowired
    private TOrderInfoMapper orderInfoMapper;
    @Autowired
    private TTerminalGoodsInfoMapper terminalGoodsInfoMapper;
    @Autowired
    private TUserDefaultInfoMapper userDefaultInfoMapper;
    @Autowired
    private TUserAddressInfoMapper userAddressInfoMapper;
    @Autowired
    private TTerminalGoodsSpeInfoMapper terminalGoodsSpeInfoMapper;
    @Autowired
    private TGoldDealSerialInfoMapper goldDealSerialInfoMapper;
    @Autowired
    private TGoldAwardSerialInfoMapper goldAwardSerialInfoMapper;
    @Autowired
    private TAboutUsInfoMapper aboutUsInfoMapper;
    @Autowired
    private TShipperCodeInfoMapper shipperCodeInfoMapper;
    @Autowired
    private TSelfPickupPointInfoMapper tSelfPickupPointInfoMapper;

    @Autowired
    private WeCatUtils weCatUtils; //微信业务处理类
    @Autowired
    private CommonUtils commonUtils; //公共业务处理类
    @Autowired
    private ICommonService commonService;
    @Autowired
    private IOrderTaskService orderTaskService;
    @Autowired
    private Environment env; //取yml配置文件信息

    //查询订单列表
    @Override
    public List<OrderListVo> queryOrderList(OrderDto orderDto) throws Exception {
        orderDto.setUserId(commonUtils.getUserId());
        PageUtil.startPage(orderDto);
        if (orderDto.getOrderStatus().equals(OrderStatusEnums.WAIT_DELIVERED.getCode())) {
            orderDto.setOrderStatus(OrderStatusEnums.WAIT_DELIVERED.getCode() + "," + OrderStatusEnums.HAS_RECEIPT.getCode());
        }
        List<OrderListVo> list = orderInfoMapper.selectTOrderInfoListForMy(orderDto);
        Optional.ofNullable(list).ifPresent(lists -> {
            lists.stream().forEach(bean -> {
                if (StringUtils.isNotEmpty(bean.getOrderStatus())) {
                    bean.setOrderStatusShow(OrderStatusEnums.getEnumsByCode(bean.getOrderStatus()).getValue());
                }
                if (StringUtils.isNotEmpty(bean.getDeliveryType())) {
                    bean.setDeliveryTypeShow(DeliveryTypeEnum.getEnumsByCode(bean.getDeliveryType()).getValue());
                }
                if (StringUtils.isNotEmpty(bean.getOrderType())) {
                    bean.setOrderTypeShow(OrderTypeEnum.getEnumsByCode(bean.getOrderType()).getValue());
                }
                bean.setPayTypeShow(bean.getPayType() == null ? "" : (bean.getPayType().equals("0") ? "微信支付" : "余额支付"));
            });
        });
        return list;
    }

    //保存订单详情
    @Override
    public OrderDetailVo saveOrderDetail(OrderDto orderDto) throws Exception {
        TOrderInfo order = new TOrderInfo();
        BeanUtils.copyProperties(orderDto, order, new String[]{"userId", "orderId", "orderNo"});
        order.setOrderStatus(OrderStatusEnums.WAIT_PAY.getCode());
        order.setId(IdUtils.simpleUUID());
        order.setOrderNo(IdUtils.getOrderNo());
        order.setCreateTime(DateUtils.getNowDate());
        order.setUserId(commonUtils.getUserId());
        TTerminalGoodsInfo goods = terminalGoodsInfoMapper.selectTTerminalGoodsInfoById(orderDto.getGoodsId());
        if (OrderTypeEnum.TERMINALPURCHASE.getCode().equals(orderDto.getOrderType())) {//终端商城购买
            TTerminalGoodsSpeInfo speInfo = terminalGoodsSpeInfoMapper.selectTTerminalGoodsSpeInfoById(orderDto.getSepId());
            order.setPayAmount(goods.getAmount().multiply(speInfo.getGoodsNum()));//终端支付金额
            order.setGoodsNum(speInfo.getGoodsNum());//终端购买数量
            if (order.getDeliveryType().equals(YesOrNoEnums.NO.getCode())) {//物流
                order.setDeliveryAmount(speInfo.getDeliveryFee());//终端配送费
            }
        } else {//兑换商城
            order.setExchangeAmount(goods.getAmount());//兑换支付金额
            order.setGoodsNum(BigDecimal.ONE);//兑换商城购买商城默认为1
            if (order.getDeliveryType().equals(YesOrNoEnums.NO.getCode())) {//物流
                order.setDeliveryAmount(goods.getDeliveryFee());//兑换配送费
            }
        }
        orderInfoMapper.insertTOrderInfo(order);
        OrderDetailVo vo = new OrderDetailVo();
        BeanUtils.copyProperties(order, vo);
        vo.setOrderId(order.getId());
        return vo;
    }

    //查询订单详情
    @Override
    public OrderDetailVo queryOrderDetail(OrderDto orderDto) throws Exception {
        OrderDetailVo vo = new OrderDetailVo();
        TOrderInfo order = orderInfoMapper.selectTOrderInfoById(orderDto.getOrderId());
        BeanUtils.copyProperties(order, vo);
        vo.setOrderId(order.getId());
        if (StringUtils.isNotEmpty(vo.getOrderStatus())) {
            vo.setOrderStatusShow(OrderStatusEnums.getEnumsByCode(vo.getOrderStatus()).getValue());
        }
        if (StringUtils.isNotEmpty(vo.getDeliveryType())) {
            vo.setDeliveryTypeShow(DeliveryTypeEnum.getEnumsByCode(vo.getDeliveryType()).getValue());
        }
        if (StringUtils.isNotEmpty(vo.getOrderType())) {
            vo.setOrderTypeShow(OrderTypeEnum.getEnumsByCode(vo.getOrderType()).getValue());
        }
        //已发货，和已完成 查看详情返回 快递公司和快递单号
        if (order.getOrderStatus().equals(OrderStatusEnums.HAS_RECEIPT.getCode()) || order.getOrderStatus().equals(OrderStatusEnums.HAS_OVER.getCode())) {
            TShipperCodeInfo tShipperCodeInfo = shipperCodeInfoMapper.selectTShipperCodeInfoCode(order.getDeliveryFirm());
            vo.setShipperName(tShipperCodeInfo == null ? null : tShipperCodeInfo.getShipperName());//快递公司名称
        }
        vo.setPayTypeShow(vo.getPayType() == null ? "" : (vo.getPayType().equals("0") ? "微信支付" : "余额支付"));
        TTerminalGoodsInfo goods = terminalGoodsInfoMapper.selectTTerminalGoodsInfoById(vo.getGoodsId());
        vo.setGoodsName(goods.getGoodsName());//商品名称
        vo.setGoodsImg(goods.getGoodsImg());//商品图片
        vo.setAmount(goods.getAmount());//商品单价
        vo.setExchangeUnit(goods.getExchangeUnit());////兑换单位
        vo.setUnit(goods.getUnit());////兑换单位
        List<TAboutUsInfo> tAboutUsInfos = aboutUsInfoMapper.selectTAboutUsInfoList(new TAboutUsInfo());
        if (order.getDeliveryType().equals(YesOrNoEnums.YES.getCode())){//等零就是自提
            TSelfPickupPointInfo info = tSelfPickupPointInfoMapper.selectTSelfPickupPointInfoById(order.getSelfId());
            if (StringUtils.isNotNull(info)){
                vo.setSelfPhone(info.getPhone());//自提点联系电话
                vo.setSelfName(info.getShopName());//自提点名称
            }
        }

        vo.setServicePhone(tAboutUsInfos.get(0).getPhone());//客服电话

        return vo;
    }

    //订单支付
    @Override
    @Transactional
    public Map<String, Object> orderPay(OrderDto orderDto) throws Exception {
        String userId = commonUtils.getUserId();
        TUserInfo user = userInfoMapper.selectTUserInfoByUserId(userId);
        TOrderInfo order = orderInfoMapper.selectTOrderInfoById(orderDto.getOrderId());
        String pay = orderDto.getPayType();//支付方式;
        String passWord = orderDto.getPassWord();
        BeanUtils.copyProperties(order, orderDto);
        paramsCheck(user, orderDto); //参数校验//公共方法
        BeanUtils.copyProperties(orderDto, order);
        if (!order.getOrderStatus().equals(OrderStatusEnums.WAIT_PAY.getCode())) {
            throw new RuntimeException("当前订单状态：" + OrderStatusEnums.getEnumsByCode("").getValue() + "，不能进行支付操作！");
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        order.setPayAmount(orderDto.getPayAmount());
        order.setExchangeAmount(orderDto.getExchangeAmount());
        order.setDeliveryAmount(orderDto.getDeliveryAmount());
        if (YesOrNoEnums.YES.getCode().equals(pay)) { //微信支付
            order.setOrderStatus(OrderStatusEnums.WAIT_PAY.getCode()); //更新订单状态
            resultMap = weCatUtils.payment(user.getOpenId(), orderDto.getOrderId(), "付款给：" + env.getProperty("wx.mchId"), env.getProperty("wx.wxNotifyUrl"), (orderDto.getPayAmount() == null? BigDecimal.ZERO : orderDto.getPayAmount()).add(orderDto.getDeliveryAmount()));
            if (resultMap.get("payStatus").equals("2")) {
                throw new RuntimeException("支付失败");
            }

            order.setPrepayTime(DateUtils.getNowDate());
            order.setPrepayInfo(JsonUtils.mapToJson(resultMap));
            order.setPayType(YesOrNoEnums.YES.getCode());//微信支付
        } else { //余额支付
            TUserInfo userInfo = userInfoMapper.selectTUserInfoByUserId(userId);
            order.setOrderStatus(OrderStatusEnums.WAIT_PAY.getCode()); //更新订单状态
            if (StringUtils.isNotEmpty(passWord)) {
                if (StringUtils.isNotEmpty(userInfo.getPaySalt()) && StringUtils.isNotEmpty(userInfo.getPayPassword())){
                    if (!userInfo.getPayPassword().equals(SaltUtils.salt(passWord, userInfo.getPaySalt()))) {
                        throw new RuntimeException("密码错误");
                    }else {
                        order.setOrderStatus(OrderStatusEnums.WAIT_DELIVERED.getCode());
                    }
                }else {
//                    throw new RuntimeException("请设置支付密码");
                    resultMap.put("setPass","301");
                    return resultMap;
                }
            }
            if ((user.getBalanceSum().subtract(user.getBalanceUse()).subtract(user.getBalanceWithdraw()).compareTo((orderDto.getPayAmount() == null ? BigDecimal.ZERO : orderDto.getPayAmount()).add(orderDto.getDeliveryAmount())) < 0)) {
                throw new RuntimeException("余额不足");
            }
            //减去用户余额，记录操作流水，更新订单状态
            user.setBalanceUse(user.getBalanceUse().add(orderDto.getPayAmount() == null ?BigDecimal.ZERO :orderDto.getPayAmount()).add(orderDto.getDeliveryAmount()));//用户已使用余额（用户已使用余额+订单余额+配送费）
            order.setPayTime(DateUtils.getNowDate());
            order.setPayType(YesOrNoEnums.NO.getCode());//余额支付
            String orderType= "";
            if (orderDto.getOrderType().equals(TransTypeEnum.YUE.getCode())){//终端购买
                orderType = TransOperTypeEnum.YUE_1001.getCode();
            }else {
                orderType = TransOperTypeEnum.YUE_1011.getCode();//兑换邮费
            }
            //插入交易流水记录表
            TUserDefaultInfo defaultInfo = commonUtils.generateTUserDefaultInfo(
                    user.getUserId(),
                    order.getBrandId(),
                    TransTypeEnum.YUE.getCode(),
                    orderType,
                    BigDecimal.ZERO.subtract((orderDto.getPayAmount() == null ? BigDecimal.ZERO : orderDto.getPayAmount()).add(orderDto.getDeliveryAmount())),
                    order.getId(),
                    "",
                    null,
                    "",
                    null);

            userDefaultInfoMapper.insertTUserDefaultInfo(defaultInfo);
            if (!OrderTypeEnum.TERMINALPURCHASE.getCode().equals(order.getOrderType())) {
                commonService.handleExchangeOrder(order, user);
            }
        }
        userInfoMapper.updateTUserInfo(user);
        orderInfoMapper.updateTOrderInfo(order);
        return resultMap;
    }

    public void paramsCheck(TUserInfo user, OrderDto orderDto) throws Exception {
        //如果是兑换商品，需校验当前用户的积分是否充足，并将对应积分或序列号或金币转给对方，同时减去本人的数量
        if (!OrderTypeEnum.TERMINALPURCHASE.getCode().equals(orderDto.getOrderType())) {
            if (OrderTypeEnum.INTEGRALEXCHANGE.getCode().equals(orderDto.getOrderType())) { //积分兑换
                if ((user.getIntegralSum().subtract(user.getIntegralExchange()).compareTo(orderDto.getExchangeAmount()) < 0)) {
                    throw new RuntimeException("您当前积分无法兑换此商品");
                }
            } else if (OrderTypeEnum.TRANEXCHANGE.getCode().equals(orderDto.getOrderType())) { //交易金兑换
                if ((user.getDealGoldMark().subtract(user.getDealGoldExchangeMark()).compareTo(orderDto.getExchangeAmount()) < 0)) {
                    throw new RuntimeException("您当前交易金无法兑换此商品");
                }
            } else if (OrderTypeEnum.BONUSEXCHANGE.getCode().equals(orderDto.getOrderType())) { //奖励金兑换
                if ((user.getAwardGoldMark().subtract(user.getAwardGoldExchangeMark()).compareTo(orderDto.getExchangeAmount()) < 0)) {
                    throw new RuntimeException("您当前奖励金无法兑换此商品");
                }
            } else if (OrderTypeEnum.GOLDEXCHANGE.getCode().equals(orderDto.getOrderType())) { //金币兑换
                if ((user.getGoldSum().subtract(user.getGoldExchange()).compareTo(orderDto.getExchangeAmount()) < 0)) {
                    throw new RuntimeException("您当前金币无法兑换此商品");
                }
            }
        } else {
            if (StringUtils.isEmpty(orderDto.getSepId())) {
                throw new RuntimeException("请选择商品规格");
            }
        }
    }

    //取消订单
    @Override
    @Transactional
    public void cancelOrder(OrderDto orderDto) throws Exception {
        TOrderInfo order = orderInfoMapper.selectTOrderInfoById(orderDto.getOrderId());
        if ("".equals(OrderStatusEnums.WAIT_PAY.getCode())) {
            throw new RuntimeException("当前订单状态：" + OrderStatusEnums.getEnumsByCode("").getValue() + "，不能进行取消操作！");
        }
        order.setOrderStatus(OrderStatusEnums.TIMEOUT_CLOSE.getCode());
        order.setDeliverGoodsTime(DateUtils.getNowDate());
        orderInfoMapper.updateTOrderInfo(order);
    }

    //确认收货
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void confirmReceipt(OrderDto orderDto) throws Exception {
        TOrderInfo order = orderInfoMapper.selectTOrderInfoById(orderDto.getOrderId());
        if (!order.getOrderStatus().equals(OrderStatusEnums.HAS_RECEIPT.getCode())) {
            throw new RuntimeException("当前订单状态：" + OrderStatusEnums.getEnumsByCode("").getValue() + "，不能进行确认收货操作！");
        }
        orderTaskService.closeTimeoutOrders(order.getId()); //调用自动关单的逻辑
    }

    //终端申领，兑换商品数据回调
    @Override
    public Map<String, Object> queryConfirmOrder(OrderDto orderDto) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        String userId = commonUtils.getUserId();
        ConfirmOrderVo vo = new ConfirmOrderVo();
        TTerminalGoodsInfo terminalGoodsInfo = terminalGoodsInfoMapper.selectTTerminalGoodsInfoById(orderDto.getGoodsId());
        BeanUtils.copyProperties(terminalGoodsInfo, vo);
        if (orderDto.getOrderType().equals(YesOrNoEnums.YES.getCode())) {//终端商城
            TTerminalGoodsSpeInfo tTerminalGoodsSpeInfo = terminalGoodsSpeInfoMapper.selectTTerminalGoodsSpeInfoById(orderDto.getSepId());//终端商城规格
            vo.setSepId(orderDto.getSepId());//规格id
            vo.setDeliveryFee(tTerminalGoodsSpeInfo.getDeliveryFee());//终端商城配送费
            vo.setGoodsNum(tTerminalGoodsSpeInfo.getGoodsNum());//终端数量
            vo.setPayAmount(terminalGoodsInfo.getAmount().multiply(tTerminalGoodsSpeInfo.getGoodsNum()));//支付金额(终端的单价 * 终端的数量)
        }

        returnMap.put("queryConfirmOrder", vo);//兑换商城，终端商城回调

        //用户默认收货地址
        TUserAddressVo addressVo = new TUserAddressVo();
        addressVo.setIsValid(YesOrNoEnums.NO.getCode());
        addressVo.setUserId(userId);
        List<TUserAddressInfo> addressInfo = userAddressInfoMapper.selectTUserAddressInfoVo(addressVo);
        if (addressInfo.size() != 0L) {
            BeanUtils.copyProperties(addressInfo.get(0), addressVo);
        }

        returnMap.put("addressVo", addressVo);

        //用户当前可用余额//可用积分
        TUserInfo userInfo = userInfoMapper.selectTUserInfoByUserId(userId);
        returnMap.put("balance", (userInfo.getBalanceSum().subtract(userInfo.getBalanceWithdraw()).subtract(userInfo.getBalanceUse())));//余额

        returnMap.put("integral", userInfo.getIntegralSum().subtract(userInfo.getIntegralExchange()));//当前可用积分

        returnMap.put("gold", userInfo.getGoldSum().subtract(userInfo.getGoldExchange()).subtract(userInfo.getGoldWithdraw()));//当前可用金币

        returnMap.put("dealBalance", goldDealSerialInfoMapper.queryDealCount(userId));//奖励金序列号数量

        returnMap.put("awardBalance", goldAwardSerialInfoMapper.queryAwardCount(userId));//交易金序列号数量

        return returnMap;
    }


}
